home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
prev
/
prev.lha
/
expr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-29
|
5KB
|
306 lines
#include <stdio.h>
#include <math.h>
#include "art.h"
float eval_fexpr();
static symbol *vars = (symbol *)NULL;
/*
* defvar
*
* define a variable
*/
defvar(s, e)
char *s;
expression *e;
{
symbol *var;
var = insertsym(&vars, s);
var->type = e->type;
switch (e->type) {
case EXP_FLOAT:
var->u.f = e->u.f;
break;
case EXP_INT:
var->u.i = e->u.i;
break;
default:
fatal("art: bad expression in defvar.\n");
}
free(e);
}
/*
* get_varexpr
*
* create an expression node for a variable.
*/
expression *
get_varexpr(s)
char *s;
{
expression *e;
symbol *sym;
char buf[BUFSIZ];
e = (expression *)smalloc(sizeof(expression));
if ((sym = findsym(vars, s)) == (symbol *)NULL) {
sprintf(buf, "art: variable %s not defined.\n", s);
fatal(buf);
}
e->type = sym->type;
switch (e->type) {
case EXP_FLOAT:
e->u.f = sym->u.f;
break;
case EXP_INT:
e->u.i = sym->u.i;
break;
default:
fatal("art: bad variable in get_varexpr.\n");
}
return(e);
}
/*
* get_ival
*
* retrieve a symbol value returning an int.
*/
int
get_ival(s)
char *s;
{
int i;
symbol *sym;
char buf[BUFSIZ];
sym = findsym(vars, s);
if (sym == (symbol *)NULL) {
sprintf(buf, "art: symbol %s not defined.\n", s);
fatal(buf);
}
if (sym->type == EXP_INT)
i = sym->u.i;
else if (sym->type == EXP_FLOAT)
i = sym->u.f;
return(i);
}
/*
* get_fval
*
* retrieve a symbol value returning a float.
*/
float
get_fval(s)
char *s;
{
float f;
symbol *sym;
char buf[BUFSIZ];
sym = findsym(vars, s);
if (sym == (symbol *)NULL) {
sprintf(buf, "art: symbol %s not defined.\n", s);
fatal(buf);
}
if (sym->type == EXP_INT)
f = sym->u.i;
else if (sym->type == EXP_FLOAT)
f = sym->u.f;
return(f);
}
/*
* get_type
*
* work the return type for an expression
*/
int
get_type(type, left, right)
int type;
expression *left, *right;
{
if (right == (expression *)NULL)
return(left->type);
if (left->type == EXP_FLOAT && right->type == EXP_FLOAT)
return(EXP_FLOAT);
if (left->type == EXP_INT && right->type == EXP_INT)
return(EXP_INT);
if (left->type == EXP_INT && right->type == EXP_FLOAT)
return(EXP_FLOAT);
if (left->type == EXP_FLOAT && right->type == EXP_INT)
return(EXP_FLOAT);
return(type);
}
/*
* eval_fexpr
*
* evaluate a floating point expression
*/
float
eval_fexpr(e)
expression *e;
{
float f;
switch (e->type) {
case EXP_INT:
f = e->u.i;
free(e);
break;
case EXP_FLOAT:
f = e->u.f;
free(e);
break;
default:
fatal("art: bad type in eval_fexpr.\n");
}
return(f);
}
/*
* eval_iexpr
*
* evaluate an integer expression
*/
int
eval_iexpr(e)
expression *e;
{
int i;
switch (e->type) {
case EXP_INT:
i = e->u.i;
free(e);
break;
case EXP_FLOAT:
i = e->u.f;
free(e);
break;
default:
fatal("art: bad type in eval_iexpr.\n");
}
return(i);
}
/*
* get_expr
*
* get an expression node, compressing it if possible
*/
expression *
get_expr(type, left, right)
int type;
expression *left, *right;
{
int ntype;
expression *expr;
ntype = get_type(type, left, right);
expr = (expression *)smalloc(sizeof(expression));
switch (type) {
case EXP_UMINUS:
switch (ntype) {
case EXP_FLOAT:
expr->type = EXP_FLOAT;
expr->u.f = -eval_fexpr(left);
break;
case EXP_INT:
expr->type = EXP_INT;
expr->u.i = -eval_iexpr(left);
break;
default:
fatal("art: bad subexpression type in get_expr.\n");
}
break;
case EXP_ADD:
switch (ntype) {
case EXP_FLOAT:
expr->type = EXP_FLOAT;
expr->u.f = eval_fexpr(left) + eval_fexpr(right);
break;
case EXP_INT:
expr->type = EXP_INT;
expr->u.i = eval_iexpr(left) + eval_iexpr(right);
break;
default:
fatal("art: bad subexpression type in get_expr.\n");
}
break;
case EXP_SUB:
switch (ntype) {
case EXP_FLOAT:
expr->type = EXP_FLOAT;
expr->u.f = eval_fexpr(left) - eval_fexpr(right);
break;
case EXP_INT:
expr->type = EXP_INT;
expr->u.i = eval_iexpr(left) - eval_iexpr(right);
break;
default:
fatal("art: bad subexpression type in get_expr.\n");
}
break;
case EXP_DIV:
switch (ntype) {
case EXP_FLOAT:
expr->type = EXP_FLOAT;
expr->u.f = eval_fexpr(left) / eval_fexpr(right);
break;
case EXP_INT:
expr->type = EXP_INT;
expr->u.i = eval_iexpr(left) / eval_iexpr(right);
break;
default:
fatal("art: bad subexpression type in get_expr.\n");
}
break;
case EXP_MUL:
switch (ntype) {
case EXP_FLOAT:
expr->type = EXP_FLOAT;
expr->u.f = eval_fexpr(left) * eval_fexpr(right);
break;
case EXP_INT:
expr->type = EXP_INT;
expr->u.i = eval_iexpr(left) * eval_iexpr(right);
break;
default:
fatal("art: bad subexpression type in get_expr.\n");
}
break;
default:
fatal("art: bad expression type in get_expr.\n");
}
return(expr);
}